﻿using Microsoft.Win32;
using SCADA_SANEST.Helpers;
using SCADA_SANEST.Models;
using SCADA_SANEST.ViewModels.Line_1;
using SCADA_SANEST.Views.Line_1;
using SCADA_SANEST.ViewModels.Line_2;
using SCADA_SANEST.Views.Line_2;
using SCADA_SANEST.ViewModels.Line_3;
using SCADA_SANEST.Views.Line_3;
using SCADA_SANEST.ViewModels.Line_4;
using SCADA_SANEST.Views.Line_4;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace SCADA_SANEST.ViewModels
{
    public class DeviceViewModel : BaseViewModel
    {
        public PlcDeviceStatus Backend { get; set; }


        public bool IsConnected
        {
            get => Backend.IsConnected;
            set
            {
                Backend.IsConnected = value;
                OnPropertyChanged(nameof(IsConnected));
            }
        }

        private string _ipEditor;
        public string IpEditor
        {
            get => _ipEditor;
            set
            {
                if (_ipEditor != value)
                {
                    _ipEditor = value;
                    if (IsConnected && IsEditing)
                    {
                        ToggleConnect(); // Ngắt kết nối tạm thời khi sửa IP
                    }
                    OnPropertyChanged(nameof(IpEditor));
                }
            }
        }

        private bool _isEditing;
        public bool IsEditing
        {
            get => _isEditing;
            set
            {
                _isEditing = value;
                OnPropertyChanged(nameof(IsEditing));
            }
        }

        private string _imagePath;
        public string ImagePath
        {
            get => _imagePath;
            set
            {
                _imagePath = value;
                OnPropertyChanged(nameof(ImagePath));
            }
        }

        public ICommand ToggleEditCommand { get; }
        public ICommand SelectImageCommand { get; }
        public ICommand OpenDetailCommand { get; }

        public DeviceViewModel(PlcDeviceStatus backend)
        {
            Backend = backend;
            IpEditor = Backend.Ip;
            IsEditing = false;

            LoadIp();
            LoadImagePath();

            ToggleEditCommand = new RelayCommand<object>(_ => true, _ => ToggleEdit());
            SelectImageCommand = new RelayCommand<object>(_ => true, _ => SelectImage());
            OpenDetailCommand = new RelayCommand<object>(_ => true, _ => OpenDetail());
        }

        private void ToggleEdit()
        {
            if (IsEditing) // Đang sửa → nhấn Save
            {
                if (!IsValidIp(IpEditor))
                {
                    MessageBox.Show("Địa chỉ IP không hợp lệ. Vui lòng nhập theo định dạng 192.168.x.x", "Lỗi IP", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                Backend.Ip = IpEditor;
                SaveIp();
                SaveImagePath();
            }
            else // Nhấn Edit
            {
                IpEditor = Backend.Ip;
            }

            IsEditing = !IsEditing;
        }

        private void ToggleConnect()
        {
            if (!IsConnected)
            {
                try
                {
                    Backend.Client.Open();
                    if (Backend.Client.IsConnected)
                    {
                        IsConnected = true;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Lỗi kết nối PLC: {ex.Message}");
                    IsConnected = false;
                }
            }
            else
            {
                try
                {
                    Backend.Client.Close();
                    IsConnected = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Lỗi ngắt kết nối: {ex.Message}");
                }
            }
        }

        private void OpenDetail()
        {
            Window detailWindow;

            switch (Backend.Type)
            {
                case DeviceType.Npc1:
                    detailWindow = new Npc1View(new Npc1ViewModel(Backend));
                    break;
                case DeviceType.Npc2:
                    detailWindow = new Npc2View(new Npc2ViewModel(Backend));
                    break;
                case DeviceType.Hsl3:
                    detailWindow = new Hsl3View(new Hsl3ViewModel(Backend));
                    break;
                case DeviceType.Hbt4:
                    detailWindow = new Hbt4View(new Hbt4ViewModel(Backend));
                    break;
                default:
                    MessageBox.Show("Chưa hỗ trợ thiết bị này.");
                    return;
            }

            ShowChildWindow(detailWindow);
        }

        private void ShowChildWindow(Window child)
        {
            var mainWindow = Application.Current.MainWindow;

            child.Closed += (s, e) => mainWindow.Show();

            mainWindow.Hide();
            child.Show();
        }

        private void SelectImage()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp";
            if (dlg.ShowDialog() == true)
            {
                ImagePath = dlg.FileName;
                SaveImagePath();
                MessageBox.Show("Đã chọn ảnh: " + ImagePath);
            }
        }

        private string GetImagePathFile()
        {
            string folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DeviceImages");
            Directory.CreateDirectory(folder);
            return Path.Combine(folder, $"{Backend.Name}_image.txt");
        }

        private void SaveImagePath()
        {
            try
            {
                File.WriteAllText(GetImagePathFile(), ImagePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Lỗi lưu ảnh: {ex.Message}");
            }
        }

        private void LoadImagePath()
        {
            try
            {
                string path = GetImagePathFile();
                if (File.Exists(path))
                {
                    ImagePath = File.ReadAllText(path);
                }
                else
                {
                    ImagePath = "/Assets/plc.png";
                }
            }
            catch
            {
                ImagePath = "/Assets/plc.png";
            }
        }

        private string GetIpFilePath()
        {
            string folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DeviceConfigs");
            Directory.CreateDirectory(folder);
            return Path.Combine(folder, $"{Backend.Name}_ip.txt");
        }

        private void SaveIp()
        {
            try
            {
                File.WriteAllText(GetIpFilePath(), Backend.Ip);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Lỗi lưu IP: {ex.Message}");
            }
        }

        private void LoadIp()
        {
            try
            {
                string path = GetIpFilePath();
                if (File.Exists(path))
                {
                    Backend.Ip = File.ReadAllText(path);
                    IpEditor = Backend.Ip; // Cập nhật lên UI
                }
            }
            catch
            {
                // Bỏ qua lỗi
            }
        }

        private bool IsValidIp(string ip)
        {
            if (string.IsNullOrWhiteSpace(ip))
                return false;

            // Regex kiểm tra đúng định dạng 192.168.x.x (x = 0~255)
            string pattern = @"^192\.168\.(\d{1,3})\.(\d{1,3})$";
            var match = Regex.Match(ip, pattern);

            if (!match.Success) return false;

            // Kiểm tra giá trị 0–255
            int part3 = int.Parse(match.Groups[1].Value);
            int part4 = int.Parse(match.Groups[2].Value);

            return part3 >= 0 && part3 <= 255 && part4 >= 0 && part4 <= 255;
        }
    }
}
